package org.catspaw.cherubim.security.ss3.rbac;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.access.intercept.RequestKey;

import org.catspaw.cherubim.security.rbac.Resource;
import org.catspaw.cherubim.security.rbac.Permission;
import org.catspaw.cherubim.security.rbac.dao.ResourceDao;
import org.catspaw.cherubim.security.rbac.dao.PermissionDao;

public class PermissionBasedRequestMapFactoryBean implements
		FactoryBean<LinkedHashMap<RequestKey, Collection<ConfigAttribute>>> {

	private static final Set<String>	HTTP_METHODS	= new HashSet<String>();
	static {
		HTTP_METHODS.add("HTTP_DELETE");
		HTTP_METHODS.add("HTTP_GET");
		HTTP_METHODS.add("HTTP_HEAD");
		HTTP_METHODS.add("HTTP_OPTIONS");
		HTTP_METHODS.add("HTTP_POST");
		HTTP_METHODS.add("HTTP_PUT");
		HTTP_METHODS.add("HTTP_TRACE");
	}
	private PermissionDao				permissionDao;
	private ResourceDao					resourceDao;

	public LinkedHashMap<RequestKey, Collection<ConfigAttribute>> getObject()
			throws Exception {
		LinkedHashMap<RequestKey, Collection<ConfigAttribute>> map = new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
		List<? extends Resource> resources = resourceDao.findAll();
		for (Resource resource : resources) {
			String urlCode = resource.getCode();
			List<? extends Permission> permissions = permissionDao
					.findByDomainCode(urlCode);
			for (Permission permission : permissions) {
				String actionCode = permission.getActionCode();
				RequestKey key = null;
				if (HTTP_METHODS.contains(actionCode)) {
					//TODO 以ResourceString和operationCode为key
					key = new RequestKey(resource.getResourceString(),
					                     actionCode);
				} else {
					//TODO 以ResourceString为key
					key = new RequestKey(resource.getResourceString());
				}
				ConfigAttribute attribute = new SecurityConfig(permission
						.getCode());
				List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>(
						1);
				attributes.add(attribute);
				map.put(key, attributes);
			}
		}
		return map;
	}

	public Class<?> getObjectType() {
		return LinkedHashMap.class;
	}

	public boolean isSingleton() {
		return true;
	}

	public PermissionDao getPermissionDao() {
		return permissionDao;
	}

	public ResourceDao getResourceDao() {
		return resourceDao;
	}

	public void setPermissionDao(PermissionDao permissionDao) {
		this.permissionDao = permissionDao;
	}

	public void setResourceDao(ResourceDao resourceDao) {
		this.resourceDao = resourceDao;
	}
}
